package com.md.model.excel;

import com.md.value.ConvertType;
import com.md.value.MergeType;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.apache.commons.compress.utils.Lists;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.List;
import java.util.Objects;

import static com.md.value.html.HtmlConstants.COLSPAN_FORMAT;
import static com.md.value.html.HtmlConstants.ROWSPAN_FORMAT;

/**
 * @author 刘骄阳
 * 2024-05-14 16:10
 */
@Data
@AllArgsConstructor(staticName = "of")
public class MergeInfo {
  /**
   * 行数
   */
  private Integer rowIndex;
  /**
   * 列数
   */
  private Integer cellIndex;
  /**
   * 本列类型
   */
  private MergeType type;
  /**
   * 合并列数
   */
  private Integer mergeCellCount;
  /**
   * 合并行数
   */
  private Integer mergeRowCount;


  public static List<MergeInfo> readMergeInfoList(final List<CellRangeAddress> mergedRegions) {
    List<MergeInfo> list = Lists.newArrayList();
    mergedRegions.forEach(cellAddresses -> {
      if (Objects.equals(cellAddresses.getFirstRow(), cellAddresses.getLastRow())) {
        // 第一行等于最后一行, 说明只合并了列, 直接塞入一个列合并的实体
        list.add(MergeInfo.of(cellAddresses.getFirstRow(), cellAddresses.getFirstColumn(), MergeType.MERGE,
          getMergeCellRange(cellAddresses), 0));
        // 列合并
        for (int i = cellAddresses.getFirstColumn() + 1; i <= cellAddresses.getLastColumn(); i++) {
          // 后面的列都跳过
          list.add(MergeInfo.of(cellAddresses.getFirstRow(), i, MergeType.CONTINUE, 0, 0));
        }
      } else {
        // 第一行不等于最后一行, 说明有跨行合并, 判断是否有跨列合并
        list.add(MergeInfo.of(cellAddresses.getFirstRow(), cellAddresses.getFirstColumn(), MergeType.MERGE,
          getMergeCellRange(cellAddresses), getMergeRowRange(cellAddresses)));
        for (int i = cellAddresses.getFirstRow() + 1; i <= cellAddresses.getLastRow(); i++) {
          if (Objects.equals(cellAddresses.getFirstColumn(), cellAddresses.getLastColumn())) {
            // 说明没跨列, 跳过后面被合并的东西
            list.add(MergeInfo.of(i, cellAddresses.getFirstColumn(), MergeType.CONTINUE, 0, 0));
          } else {
            for (int j = cellAddresses.getFirstColumn() + 1; j <= cellAddresses.getLastColumn(); j++) {
              // 说明跨列了, 跳过指定行的指定列
              list.add(MergeInfo.of(i, j, MergeType.CONTINUE, 0, 0));
            }
          }
        }
      }
    });
    return list;
  }

  public static List<MergeInfo> readMergeInfo(final List<CellRangeAddress> mergedRegions) {
    List<MergeInfo> list = Lists.newArrayList();
    mergedRegions.forEach(cellAddresses -> {
      if (Objects.equals(cellAddresses.getFirstRow(), cellAddresses.getLastRow())) {
        // 第一行等于最后一行, 说明只合并了列, 直接塞入一个列合并的实体
        list.add(MergeInfo.of(cellAddresses.getFirstRow(), cellAddresses.getFirstColumn(), MergeType.MERGE,
          getMergeCellRange(cellAddresses), 0));
        // 列合并
        for (int i = cellAddresses.getFirstColumn() + 1; i <= cellAddresses.getLastColumn(); i++) {
          // 后面的列都跳过
          list.add(MergeInfo.of(cellAddresses.getFirstRow(), i, MergeType.CONTINUE, 0, 0));
        }
      } else {
        // 第一行不等于最后一行, 说明有跨行合并, 判断是否有跨列合并
        list.add(MergeInfo.of(cellAddresses.getFirstRow(), cellAddresses.getFirstColumn(), MergeType.MERGE,
          getMergeCellRange(cellAddresses), getMergeRowRange(cellAddresses)));
        for (int i = cellAddresses.getFirstRow() + 1; i <= cellAddresses.getLastRow(); i++) {
          if (Objects.equals(cellAddresses.getFirstColumn(), cellAddresses.getLastColumn())) {
            // 说明没跨列, 跳过后面被合并的东西
            list.add(MergeInfo.of(i, cellAddresses.getFirstColumn(), MergeType.CONTINUE, 0, 0));
          } else {
            for (int j = cellAddresses.getFirstColumn() + 1; j <= cellAddresses.getLastColumn(); j++) {
              // 说明跨列了, 跳过指定行的指定列
              list.add(MergeInfo.of(i, j, MergeType.CONTINUE, 0, 0));
            }
          }
        }
      }
    });
    return list;
  }

  public static Integer getMergeCellRange(final CellRangeAddress cellAddresses) {
    int mergeRange = cellAddresses.getLastColumn() - cellAddresses.getFirstColumn();
    if (mergeRange == 0) {
      return mergeRange;
    }
    return mergeRange + 1;
  }

  public static Integer getMergeRowRange(final CellRangeAddress cellAddresses) {
    int mergeRange = cellAddresses.getLastRow() - cellAddresses.getFirstRow();
    if (mergeRange == 0) {
      return mergeRange;
    }
    return mergeRange + 1;
  }

  public String getMerge(final ConvertType convertType) {
    StringBuilder merge = new StringBuilder();
    switch (convertType) {
      case EXCEL_TO_HTML:
        if (mergeRowCount != 0) {
          merge.append(String.format(ROWSPAN_FORMAT, mergeRowCount));
        }
        if (mergeCellCount != 0) {
          merge.append(String.format(COLSPAN_FORMAT, mergeCellCount));
        }
        break;
      default:
        break;
    }
    return merge.toString();
  }
}
